#ifndef __RENDER_TEXTURE_GLES_H__
#define __RENDER_TEXTURE_GLES_H__

#pragma once

#include "RendererGLESCompileConfig.h"

namespace Nezha
{

	class RenderBufferGLES : public HardwareBuffer
	{
	public:
		RenderBufferGLES(HardwareBuffer::Usage usage, u16 w, u16 h, u16 numSamples);
		~RenderBufferGLES();

		void bind2FrameBuffer(GLenum attachment);

		GLint getGLHandle() const
		{
			return mRenderBufferHandle;
		}

		GLenum getGLFormat() const
		{
			return mGLFormat;
		}

		u16 getWidth() const
		{
			return mWidth;
		}

		u16 getHeight() const
		{
			return mHeight;
		}

		u16 getNumSamples() const
		{
			return mNumSamples;
		}

		virtual void* lockImpl(u32 offset, u32 length, LockOption opt);

		virtual void unlockImpl();

		bool _initializeOnce(GLenum glFmt, u16 bitDepth);

		static GLenum Usage2GLFormat(HardwareBuffer::Usage usage, u16 bitDepth);
	private:
		GLuint mRenderBufferHandle;
		GLenum mGLFormat;
		u16 mWidth;
		u16 mHeight;
		u16 mNumSamples;
	};

	typedef RefCountedPtr<RenderBufferGLES>::Default RenderBufferGLESPtr;

	/** Internal class for depth & stencil buffer. */
	class DepthBufferGLES : public DepthStencilBuffer
	{
	public:
		DepthBufferGLES(RenderBufferGLES* depthBuf, RenderBufferGLES* stencilBuf, u16 w, u16 h, u16 multisamples);
		~DepthBufferGLES();

		virtual bool isCompatible(RenderTarget* rt) const;

		RenderBufferGLES* getDepthBuffer()
		{
			return mDepthBuffer.get();
		}

		RenderBufferGLES* getStencilBuffer()
		{
			return mStencilBuffer.get();
		}

		bool isPacked() const
		{
			return mPacked;
		}
		
	private:
		// FIXME depth buffer can be texture.
		RenderBufferGLESPtr mDepthBuffer;
		RenderBufferGLESPtr mStencilBuffer;
		u16 mMultisamples;
		bool mPacked;
	};

	typedef RefCountedPtr<DepthBufferGLES>::Default DepthBufferGLESPtr;

	class FrameBufferObject;
	class FBORTTManager;

	// only FBO for now. support no multi-rendertarget.
	class RenderTextureGLES : public RenderTarget
	{
	public:
		RenderTextureGLES(u16 w, u16 h, u16 numSamples, u16 bitDepth);

		virtual Texture* getRenderTexture(u32 index);

		virtual bool attachDepthStencilBuffer(DepthStencilBuffer* ds);

		virtual void detachDepthStencilBuffer();

		FrameBufferObject* getFBO()
		{
			return mFBO;
		}

		bool _initializeOnce(FBORTTManager* fboMgr, TexFormat fmt, bool renderTexture = false);
	private:
		FrameBufferObject* mFBO;
		u16 mNumSamples;
	};

}

#endif //end __RENDER_TEXTURE_GLES_H__